// 类 class
// 类的访问修饰符: public / private / protected
// 类的只读属性 

export {} // 确保跟其他示例没有成员冲突  


class Person {
    // 在class中，变量要先声明类型，可直接初始话或在constructor中进行初始化
    public name: string //共有成员， 默认所有的成员都是共有成员
    private age: number //private将成员定义为私有属性，只能在类的内部去使用
    protected  readonly  gender: boolean // 受保护的成员， 只允许在子类中访问受保护的成员, 先声明访问修饰符后才能修饰只读属性


    constructor(name:string, age: number ){
        // 声明后需要在constructor中赋值
        this.name = name
        this.age = age
        this.gender = true
    }

    say (msg: string): void {
        console.log(`I am ${this.name}, ${msg}`)
        console.log(this.age)
    }
}


class Student extends Person {
    // private 声明constructor后， 外部无法创建实例
    private constructor (name:string, age: number ){
        super(name, age)
        console.log(this.gender) //子类可访问受保护的成员
    }

    // 可通过static创建一个方法，使用该方法，使外部可以创建该实例
    static creat (name:string, age: number){
        return new Student(name, age)
    }
}

const tom = new Person('tom', 18)
console.log(tom.name)
// console.log(tom.age) // 外部无法是访问私有属性
// tom.gender = false // 只读属性在外部或内部都无法再被修改

// const jack = new Student() // 外部无法创建被private的实例
const jack = Student.creat('jack', 20)